// 循环  遍历  迭代

// 循环: 语言层面上的语法 -> 重复执行一段程序的方案
// 遍历: 业务层面上的做法 -> 管擦或者获取集合中的元素的一种做法
// 迭代: 实现层面上的概念 -> 实现遍历的底层方案其实就是迭代

// var arr = [0, 1, 2, 3];

// for (var i = 0; i < arr.length; i++) {
//   console.log(arr[i], i, arr); // 重复执行的程序
// }


// ECMAScript3 -> 没有针对可迭代对象的具体的遍历方法

// ECMAScript5 -> 新增7个专门针对数组的遍历方法
// ECMAScript5 -> 新增 for in 对象的遍历方法

// forEach map filter reduce reduceRight some every

// arr.forEach(function(item, index, array) {
//   console.log(item, index, array);
// })

var obj = {
  a: 1,
  b: 2,
  c: 3
}

// for ... in  以任意顺序迭代对象的可枚举属性
// 找的是对象的属性键名, 为遍历对象属性而构建的


// for (var key in obj) {
//   console.log(key, obj[key]);
// }

var arr = [1, 2, 3];
// 类数组
var arr1 = {
  0: 1,
  1: 2,
  2: 3,
  length: 3,
  slice: Array.prototype.slice,
  push: Array.prototype.push
}

var arr2 = new Map([[{a: 1}, 1], [{b: 2}, 2], [{c: 3}, 3]]);
var arr3 = new Set(['a', 'b', 'c']);

// for (var key in arr) {
//   console.log(key, arr[key]);
// }


// for ... of 遍历可迭代对象定义要迭代的数据
// 在可迭代对象上建立迭代循环  依赖 Symbol.iterator

// Object.prototype 上没有Symbol.iterator  所以使用不了 for ... of


// (function(a, b, c) {
//   console.log(arguments)
// })(1, 2, 3);

// for (let v in arr) {
//   console.log(v);
// }



// const allLi = document.getElementsByTagName('li');
// console.log(allLi);

// for (let li of allLi) { // allLi prototype 上有 Symbol.iterator
//   console.log(li.innerText);
// }

// for (let [k, v] of arr2) {
//   console.log(k, v);
// }






// 生成器(generator) 作用 -> 生成 返回 一个迭代器(iterator)
// 函数名前 加一个 *, 用 yield(暂停) 产出一个值

// function * generator(arr) {
//   for (let v in arr) {
//     yield v;
//   }
// }

// const iterator = generator(arr);

// for (let i = 0; i <= arr.length; i++) {
//   console.log(iterator.next());
// }

// console.log(iterator.next());
// // {value: 1, done: false} 执行了一次拿到第一个值, 全执行完了么: 没有

// console.log(iterator.next().value); // 1
// console.log(iterator.next().value); // 2
// console.log(iterator.next().value); // 3
// console.log(iterator.next().value); // undefined {value: undefined, done: true}



// 实现 generator

// function generator (arr) {
//   let nextIndex = 0;

//   return {
//     next() {
//       /**
//        * {
//        *  value: ?,
//        *  done: ?
//        * }
//        */
//       return nextIndex < arr.length
//       ?
//       { value: arr[nextIndex ++ ], done: false }
//       :
//       { value: undefined, done: true }
//     }
//   }
// }

// const iterator = generator(arr);

// console.log(iterator.next().value); // 1
// console.log(iterator.next().value); // 2
// console.log(iterator.next().value); // 3
// console.log(iterator.next().value); // undefined



const o = {
  0: 4,
  1: 5,
  2: 6,
  length: 3
}

// 给对象 添加一个 迭代器
Object.prototype[Symbol.iterator] = interator;

function interator() {
  var index = 0;
  var _this = this;

  return {
    next() {
      return index < _this.length
      ?
      { value: _this[index ++], done: false }
      :
      { value: undefined, done: true }
    }
  }
}

for (let v of o) {
  console.log(v)
}